package com.api.weavernorth.OcrCase;

import com.alibaba.fastjson.JSONObject;
import com.weavernorth.util.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
import sun.misc.BASE64Decoder;
import weaver.conn.RecordSet;
import weaver.file.FileUploadToPath;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
 * @Author: BruseeWang
 * @Date: 2021/4/26 18:23
 * @Description: 根据前台传过来的base64信息进行解析图片
 */
@Path("/weavernorth/OcrCase/AnalyticCard")
public class AnalyticCard {
    Logger log = Logger4jUtil.getLoggerByName("/api/OcrCase/AnalyticCard/");

    @POST
    @Path("/getCardInfo")
    @Produces(MediaType.TEXT_PLAIN)
    public String getCardInfo(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        FileUploadToPath fileUploadToPath = new FileUploadToPath(request);
        String strFrontCard = fileUploadToPath.getParameter("imageUrlFont");   //strFrontCard-formdata中二进制字段对应的name
        String strContraryCard = fileUploadToPath.getParameter("imageUrlBack");//strContraryCard-formdata中二进制字段对应的name
        String strWorkFlowId = fileUploadToPath.getParameter("wrokflowid");    //流程id
        String strOCrType = fileUploadToPath.getParameter("OCRType");          //识别类型
        String strRequestid = fileUploadToPath.getParameter("requestid");      //请求id
        log.info("身份证正面Base64---" + strFrontCard);
        log.info("身份证反面Base64---" + strContraryCard);
        log.info("流程id---" + strWorkFlowId);
        log.info("识别类型---" + strOCrType);
        // 数据库操作
        RecordSet rs = new RecordSet();
        RecordSet rs1 = new RecordSet();
        try {
            if ("identityCard".equals(strOCrType)) {
                // 根据流程id和识别类型获取APPkey和PassWord
                String strSql = "select * from uf_OCR_Page where workFlowId = '" + strWorkFlowId + "' and OcrType = '身份证'";
                log.info("获取流程数据的sql--" + strSql);
                rs.execute(strSql);
                if (rs.next()) {
                    // APPkey
                    String strAppkey = rs.getString("AppKey");
                    // PassWord
                    String strPassWord = rs.getString("PassWord");
                    // 供应商类型
                    String strSupplierType = rs.getString("SupplierType");
                    log.info("AppKey--" + strAppkey + "---strPassWord---" + strPassWord + "---strSupplierType---" + strSupplierType);

                    // 判断供应商类型
                    if ("百度".equals(strSupplierType)) {
                        // 识别操作
                        // 获取token
                        // String strAccessTokenHttp = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=K80GBy0KHNqyRLqGSnpGxrbI&client_secret=PKsyn6GeXWs22Lds0qYZ1wS3sQfleE44";
                        String strAccessTokenHttp = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + strAppkey + "&client_secret=" + strPassWord;
                        String result = "";
                        InputStream in = null;
                        HttpURLConnection connection = null;
                        String strAccessToken = "";
                        try {
                            log.info("1.创建服务地址");
                            URL SSO_url = new URL(strAccessTokenHttp);
                            log.info("2.打开连接");
                            connection = (HttpURLConnection) SSO_url.openConnection();
                            log.info("3.设置参数,GET请求方式,数据格式为json");
                            connection.setRequestProperty("Charset", "UTF-8");
                            connection.setRequestMethod("POST");
                            log.info("4.发送请求,接受服务器端响应");
                            connection.connect();
                            int responseCode = connection.getResponseCode();
                            log.info("5.服务端响应码:" + responseCode);
                            if (200 == responseCode) {
                                in = connection.getInputStream();
                                ByteArrayOutputStream bs = new ByteArrayOutputStream();
                                int n = 0;
                                byte[] datas = new byte[2048];
                                while ((n = in.read(datas)) != -1) {
                                    bs.write(datas, 0, n);
                                }
                                bs.flush();
                                bs.toByteArray();
                                result = new String(bs.toByteArray(), "utf-8");
                                JSONObject jsonObject = JSONObject.parseObject(result);
                                strAccessToken = jsonObject.getString("access_token");
                                log.info("获取到的token---" + strAccessToken);
                                log.info("6.响应结果:" + result);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.info("总线认证接口请求失败-->" + strAccessTokenHttp);
                        } finally {
                            try {
                                if (in != null) {
                                    // 关闭输入流
                                    in.close();
                                }
                                // 断开连接
                                connection.disconnect();
                            } catch (Exception e) {
                                log.info("关闭流/断开连接失败！");
                                e.printStackTrace();

                            }
                        }
                        String strCardInfoJson = "";
                        Map<String, Object> map = new HashMap<>();
                        if (strFrontCard != null && strContraryCard != null) {
                            // 将多余的部分截取出来
                            strFrontCard = strFrontCard.substring(23, strFrontCard.length() - 1);
                            log.info("正面截取后的base64---" + strFrontCard);
                            strContraryCard = strContraryCard.substring(23, strContraryCard.length() - 1);
                            log.info("反面截取后的base64---" + strContraryCard);
                            String strFrontInfo = getFilePath(strFrontCard, "front", strAccessToken, strRequestid);
                            String strBzckInfo = getFilePath(strContraryCard, "back", strAccessToken, strRequestid);
                            // 读取正面的信息
                            JSONObject fontJsonObject = JSONObject.parseObject(strFrontInfo);
                            // 读取反面的信息
                            JSONObject backJsonObject = JSONObject.parseObject(strBzckInfo);
                            // 查询此条流程配置需要显示的字段
//                        map.put("fontJsonObject", fontJsonObject);
//                        map.put("backJsonObject", backJsonObject);
                            // 查询当前流程在配置 OCR_CardFieldPage 表中所配置的字段
                            // 姓名
                            String strNameFieldId = "";
                            // 身份证编号
                            String strNumberFieldId = "";
                            // 性别
                            String strSexFieldId = "";
                            // 民族
                            String strNationFieldId = "";
                            // 出生年月
                            String strBirthFieldId = "";
                            // 家庭住址
                            String strAddressFieldId = "";
                            // 发证机关
                            String strOfficeFieldId = "";
                            // 证件开始日期 = "";
                            String strBeginTimeFieldId = "";
                            // 证件结束日期
                            String strEndTimeFieldId = "";

                            String strSql1 = "select * from  uf_OCR_CardFieldPag where workFlowId = '" + strWorkFlowId + "'";
                            log.info("获取配置字段的sql--" + strSql1);
                            rs1.execute(strSql1);
                            if (rs1.next()) {
                                strNameFieldId = rs1.getString("name");
                                strNumberFieldId = rs1.getString("num");
                                strSexFieldId = rs1.getString("sex");
                                strNationFieldId = rs1.getString("nation");
                                strBirthFieldId = rs1.getString("birth");
                                strAddressFieldId = rs1.getString("address");
                                strOfficeFieldId = rs1.getString("office");
                                strBeginTimeFieldId = rs1.getString("beginTime");
                                strEndTimeFieldId = rs1.getString("endTime");
                            } else {
                                return "-1";
                            }
                            // 将识别身份证反回来的信息进行处理与上面的字段id进行拼接json
                            // 正面
                            String strFontWords = fontJsonObject.getString("words_result");
                            String strBackWords = backJsonObject.getString("words_result");
                            JSONObject strFontWordsObject = (JSONObject) packageJson(strFontWords);
                            JSONObject strBackWordsObject = (JSONObject) packageJson(strBackWords);


                            String strCardObjects = strFontWordsObject.getString("姓名");
                            JSONObject ObjectName = (JSONObject) packageJson(strCardObjects);
                            String strCardName = ObjectName.getString("words");
                            log.info("获取到的姓名---" + strCardName);

                            strCardObjects = strFontWordsObject.getString("民族");
                            ObjectName = (JSONObject) packageJson(strCardObjects);
                            String strCardNation = ObjectName.getString("words");
                            log.info("获取到的民族---" + strCardNation);


                            strCardObjects = strFontWordsObject.getString("住址");
                            ObjectName = (JSONObject) packageJson(strCardObjects);
                            String strCardAdderss = ObjectName.getString("words");
                            log.info("获取到的住址--" + strCardAdderss);

                            strCardObjects = strFontWordsObject.getString("公民身份号码");
                            ObjectName = (JSONObject) packageJson(strCardObjects);
                            String strCardNo = ObjectName.getString("words");
                            log.info("获取到的身份证号--" + strCardNo);

                            strCardObjects = strFontWordsObject.getString("出生");
                            ObjectName = (JSONObject) packageJson(strCardObjects);
                            String strCardBirth = ObjectName.getString("words");
                            log.info("获取到的出生--" + strCardBirth);

                            strCardObjects = strFontWordsObject.getString("性别");
                            ObjectName = (JSONObject) packageJson(strCardObjects);
                            String strCardSex = ObjectName.getString("words");
                            log.info("获取到的性别--" + strCardSex);


                            strCardObjects = strBackWordsObject.getString("签发日期");
                            ObjectName = (JSONObject) packageJson(strCardObjects);
                            String strCardBeginTime = ObjectName.getString("words");
                            log.info("获取到的签发日期--" + strCardBeginTime);

                            strCardObjects = strBackWordsObject.getString("签发机关");
                            ObjectName = (JSONObject) packageJson(strCardObjects);
                            String strCardOffice = ObjectName.getString("words");
                            log.info("获取到的签发机关--" + strCardOffice);

                            strCardObjects = strBackWordsObject.getString("失效日期");
                            ObjectName = (JSONObject) packageJson(strCardObjects);
                            String strCardEndTime = ObjectName.getString("words");
                            log.info("获取到的失效日期--" + strCardEndTime);

                            // 拼接Json
                            JSONObject NameJson = new JSONObject();
                            NameJson.put("fieldId", strNameFieldId);
                            NameJson.put("value", strCardName);

                            JSONObject NationJson = new JSONObject();
                            NationJson.put("fieldId", strNationFieldId);
                            NationJson.put("value", strCardNation);

                            JSONObject NnumberJson = new JSONObject();
                            NnumberJson.put("fieldId", strNumberFieldId);
                            NnumberJson.put("value", strCardNo);

                            JSONObject SexJson = new JSONObject();
                            SexJson.put("fieldId", strSexFieldId);
                            SexJson.put("value", strCardSex);

                            JSONObject BirthJson = new JSONObject();
                            BirthJson.put("fieldId", strBirthFieldId);
                            BirthJson.put("value", strCardBirth);

                            JSONObject AddressJson = new JSONObject();
                            AddressJson.put("fieldId", strAddressFieldId);
                            AddressJson.put("value", strCardAdderss);

                            JSONObject OfficeJson = new JSONObject();
                            OfficeJson.put("fieldId", strOfficeFieldId);
                            OfficeJson.put("value", strCardOffice);

                            JSONObject BeginTimeJson = new JSONObject();
                            BeginTimeJson.put("fieldId", strBeginTimeFieldId);
                            BeginTimeJson.put("value", strCardBeginTime);

                            JSONObject EndTimeJson = new JSONObject();
                            EndTimeJson.put("fieldId", strEndTimeFieldId);
                            EndTimeJson.put("value", strCardEndTime);

                            map.put("name", NameJson);
                            map.put("nation", NationJson);
                            map.put("number", NnumberJson);
                            map.put("sex", SexJson);
                            map.put("birth", BirthJson);
                            map.put("address", AddressJson);
                            map.put("office", OfficeJson);
                            map.put("beginTime", BeginTimeJson);
                            map.put("endTime", EndTimeJson);
                        }
                        log.info("将map类型的Json数组返回到前台");
                        return JSONObject.toJSONString(map);

                    } else if ("腾讯".equals(strSupplierType)) {
                        //todo
                        log.info("基于腾讯供应商的代码待开发");
                        return "";
                    }
                } else {
                    // 代表没有配置当前的流程中当前的识别类型
                    return "1";
                }
            } else if ("驾驶证".equals(strOCrType)) {
                return "3";
            }
        }catch (Exception ex){
            log.info("程序异常,异常信息为："+ex.toString());
            return "0";
        }
        return "2";
    }


    /****
     * 根据workflowid获取字段名
     * @param request
     * @param response
     * @return
     */
    @GET
    @Path("/getFiledName")
    @Produces(MediaType.TEXT_PLAIN)
    public String getFiledName(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        // workFlowId
        String strWorkFlowId = request.getParameter("wrokflowid");
        // 识别类型
        String strOCRType = request.getParameter("OCRType");

        String strFiledName = "";
        String strFieldId = "";
        // 数据库操作
        RecordSet rs = new RecordSet();
        RecordSet rs1 = new RecordSet();
        RecordSet rs2 = new RecordSet();
        Map<String, String> map = new HashMap<>();
        String strSql = "select a.labelname from HtmlLabelInfo a INNER JOIN workflow_billfield b on a.indexid=b.fieldlabel  where a.indexid in (select fieldlabel from workflow_billfield where billid = (select formid from  workflow_base  where id = '" + strWorkFlowId + "') and fielddbtype != 'int' and fieldhtmltype != '3' and fieldhtmltype != '4' and fieldhtmltype != '5') and languageid = '7'";
        log.info("获取字段显示名的sql---" + strSql);
        rs.execute(strSql);
        while (rs.next()) {
            strFiledName = strFiledName + rs.getString("labelname") + ",";
        }
        // 去掉最后一个逗号
        strFiledName = strFiledName.substring(0, strFiledName.length() - 1);
        log.info("获取到名字的字符串---" + strFiledName);
        // 获取 workflow_billfield 表中的id字段对应的是显示名所对应的fieldId
//        String strSql1 = "select FIELDNAME field from workflow_billfield where billid = (select formid from  workflow_base  where id = '" + strWorkFlowId + "') and fielddbtype != 'int' and fieldhtmltype != '3' and fieldhtmltype != '4' and fieldhtmltype != '5'";
        String strSql1 = "select b.id from HtmlLabelInfo a INNER JOIN workflow_billfield b on a.indexid=b.fieldlabel  where a.indexid in (select fieldlabel from workflow_billfield where billid = (select formid from  workflow_base  where id = '" + strWorkFlowId + "') and fielddbtype != 'int' and fieldhtmltype != '3' and fieldhtmltype != '4' and fieldhtmltype != '5') and languageid = '7'";
        log.info("获取workflow_billfield 中的 field 的sql--" + strSql1);
        rs1.execute(strSql1);
        while (rs1.next()) {
            strFieldId = strFieldId + rs1.getString("id") + ",";
        }
        // 去掉最后一个逗号
        strFieldId = strFieldId.substring(0, strFieldId.length() - 1);
        map.put("FieldName", strFiledName);
        map.put("FieldId", strFieldId);
        // 根据当前传过来的workflowid去数据库中查找是否已经有这条数据
        // 姓名
        String strName = "";
        // 身份证编号
        String strNumber = "";
        // 性别
        String strSex = "";
        // 民族
        String strNation = "";
        // 出生年月
        String strBirth= "";
        // 家庭住址
        String strAddress = "";
        // 发证机关
        String strOffice = "";
        // 证件开始日期 = "";
        String strBeginTime = "";
        // 证件结束日期
        String strEndTime = "";

        String strSql2 = "select * from  uf_OCR_CardFieldPag where workFlowId = '" + strWorkFlowId + "'";
        log.info("获取配置字段的sql--" + strSql2);
        rs2.execute(strSql2);
        if (rs2.next()) {
            strName = rs2.getString("name");
            strNumber = rs2.getString("num");
            strSex = rs2.getString("sex");
            strNation = rs2.getString("nation");
            strBirth = rs2.getString("birth");
            strAddress = rs2.getString("address");
            strOffice = rs2.getString("office");
            strBeginTime = rs2.getString("beginTime");
            strEndTime = rs2.getString("endTime");
        }
        map.put("strName", strName);
        map.put("strNumber", strNumber);
        map.put("strSex", strSex);
        map.put("strNation", strNation);
        map.put("strBirth", strBirth);
        map.put("strAddress", strAddress);
        map.put("strOffice", strOffice);
        map.put("strBeginTime", strBeginTime);
        map.put("strEndTime", strEndTime);
        return JSONObject.toJSONString(map);
    }

    /**
     * 将Base64串生成身份证信息
     *
     * @Param: 图片生成的Base64串, 人名，身份证正反面，token
     * @return: 图片路径
     */

    public String getFilePath(String strBase64, String strType, String strAccessToken, String strRequestid) {
        String param = "";
        String strResult = "";
        try {
            // 请求url
            String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
            log.info("url --" + url);
            // 进行循环识别
            BASE64Decoder decoder = new BASE64Decoder();
            //Base64解码
            byte[] b = decoder.decodeBuffer(strBase64);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {//调整异常数据
                    b[i] += 256;
                }
            }
            File folder = new File("/FJ/附件" + strRequestid + "");  // 更改为服务器地址，相对路径
            log.info("folder----" + folder);
            log.info(!folder.exists());
            if (!folder.exists() || !folder.isDirectory()) {//若此目录不存在，则创建之
                folder.mkdirs();
            }
            String imgFilePath = "/FJ/附件" + strRequestid + "/" + strType + "面" + strRequestid + ".jpg";//新生成的图片

            log.info("生成的图片---" + imgFilePath);
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            out.close();
            log.info("取到的图片---" + imgFilePath);
            byte[] imgData = FileUtil.readFileByBytes(imgFilePath);
            String imgStr = MyCrypUtils.Base64Encode(imgData);
            String StrImgParam = URLEncoder.encode(imgStr, "UTF-8");
            if ("front".equals(strType)) {
//                param = "id_card_side=front&detect_direction=true&image=" + StrImgParam;
                param = "id_card_side=front&image=" + StrImgParam;
                strResult = HttpUtil.post(url, strAccessToken, param);
                log.info("获取的正面的身份证信息---" + strResult);
            } else if ("back".equals(strType)) {
//                param = "id_card_side=back&detect_direction=true&image=" + StrImgParam;
                param = "id_card_side=back&image=" + StrImgParam;
                strResult = HttpUtil.post(url, strAccessToken, param);
                log.info("获取的反面的身份证信息---" + strResult);
            }

        } catch (IOException e) {
            log.info("异常---" + e.toString());
        } catch (Exception e) {
            log.info("异常---" + e.toString());

        }
        return strResult;
    }

    public Object packageJson(String strJson) {
        JSONObject jsonObject = JSONObject.parseObject(strJson);
        return jsonObject;
    }
}
